package com.zqh.irmadscore.service.impl;


import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zqh.irmadscore.service.CombinationService;
import com.zqh.irmadscore.service.FailureTypeService;
import com.zqh.irmadscore.service.TractAlertService;
import com.zqh.irmadscore.service.TractsService;
import com.zqh.irmadscore.mapper.CombinationMapper;
import com.zqh.irmadscore.model.dto.CombinationDTO;
import com.zqh.irmadscore.model.dto.TractAlertDTO;
import com.zqh.irmadscore.model.dto.TractCombinationDTO;
import com.zqh.irmadscore.model.entity.FailureType;
import com.zqh.irmadscore.model.entity.MonitoringTracts;
import com.zqh.irmadscore.model.entity.TractAlert;
import com.zqh.irmadscore.model.entity.TractsCombination;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

@Service
@RequiredArgsConstructor
public class CombinationServiceImpl extends ServiceImpl<CombinationMapper, TractsCombination> implements CombinationService {


    private final TractsService tractsService;

    @Override
    public List<TractCombinationDTO> getTractCombinationDTO() {

        List<TractsCombination> tractsCombinationList = this.list();

        List<TractCombinationDTO> listDTOS = new ArrayList<>();


//        for (TractsCombination tractsCombination : tractsCombinationList) {
//            System.out.println(tractsCombination);
//            List<MonitoringTracts> tractsList = new ArrayList<>();
//
//            if (tractsCombination.getTractId1() != null) {
//                // 根据id找监测道
//                MonitoringTracts tract =
//                        tractsService.getById(tractsCombination.getTractId1());
//                tractsList.add(tract);
//            }
//            // 2,3,4,5也是这样
//            if (tractsCombination.getTractId2() != null) {
//                MonitoringTracts tract =
//                        tractsService.getById(tractsCombination.getTractId2());
//                tractsList.add(tract);
//            }
//            if (tractsCombination.getTractId3() != null) {
//                MonitoringTracts tract =
//                        tractsService.getById(tractsCombination.getTractId3());
//                tractsList.add(tract);
//            }
//            if (tractsCombination.getTractId4() != null) {
//                MonitoringTracts tract =
//                        tractsService.getById(tractsCombination.getTractId4());
//                tractsList.add(tract);
//            }
//            if (tractsCombination.getTractId5() != null) {
//                MonitoringTracts tract =
//                        tractsService.getById(tractsCombination.getTractId5());
//                tractsList.add(tract);
//            }
//
//            TractCombinationDTO tractCombinationDTO = TractCombinationDTO.builder()
//                    .tracts(tractsList)
//                    .combinationId(tractsCombination.getId())
//                    .failureId(tractsCombination.getFailureId())
//                    .build();
//
//            listDTOS.add(tractCombinationDTO);
//        }


        return listDTOS;
    }

    private final FailureTypeService failureTypeService;
    private final TractAlertService tractAlertService;

//    private final TractsService tractsService;

    /**
     * 获取所有组合信息，并将其转换为CombinationDTO列表。
     * 该方法首先从数据库中获取所有的TractsCombination对象，然后为每个组合生成一个CombinationDTO对象。
     * 每个CombinationDTO对象包含组合的ID和内容，内容是该组合中所有MonitoringTracts对象的字符串表示。
     *
     * @return List<CombinationDTO> 返回包含所有组合信息的CombinationDTO列表。
     */
    @Override
    public List<CombinationDTO> getCombinationInfo() {

        // 获取所有的TractsCombination对象
        List<TractsCombination> tractsCombinationList = this.list();

        // 初始化CombinationDTO列表
        List<CombinationDTO> combinationDTOS = new ArrayList<>();

        // 遍历每个TractsCombination对象
        for (TractsCombination tractsCombination : tractsCombinationList) {


            // 获取当前组合中的所有tractId
            List<Integer> tractAlertIds = Arrays.asList(
                    tractsCombination.getTractAlertId1(),
                    tractsCombination.getTractAlertId2(),
                    tractsCombination.getTractAlertId3(),
                    tractsCombination.getTractAlertId4(),
                    tractsCombination.getTractAlertId5()
            );


            // 使用流处理 tractAlertIds 列表，过滤掉空值，根据 ID 获取对应的对象，并再次过滤掉可能的空值，最终收集结果到一个新的列表中
            List<TractsCombination> combinationList = tractAlertIds.stream()
                    .filter(ObjectUtil::isNotEmpty) // 过滤掉空的警报 ID
                    .map(this::getById) // 根据警报 ID 获取对应的 TractsCombination 对象
                    .filter(ObjectUtil::isNotEmpty)
                    .toList();


            List<TractAlertDTO> alertDTOS = new ArrayList<>();
            for (var combination : combinationList) {


                TractAlert alert1 = tractAlertService.getById(combination.getTractAlertId1());
                var alert2 = tractAlertService.getById(combination.getTractAlertId2());
                var alert3 = tractAlertService.getById(combination.getTractAlertId3());
                var alert4 = tractAlertService.getById(combination.getTractAlertId4());
                var alert5 = tractAlertService.getById(combination.getTractAlertId5());

                List<TractAlert> alerts = new ArrayList<>();
                if (alert1 != null) alerts.add(alert1);
                if (alert2 != null) alerts.add(alert2);
                if (alert3 != null) alerts.add(alert3);
                if (alert4 != null) alerts.add(alert4);
                if (alert5 != null) alerts.add(alert5);

                List<MonitoringTracts> tracts = new ArrayList<>();

                int t = 1;
                for (var alert : alerts) {

                    var tractId = alert.getTractId();
                    MonitoringTracts tract = tractsService.getById(tractId);
                    tracts.add(tract);

                    TractAlertDTO alertDTO = TractAlertDTO
                            .builder()
                            .tracts(tract)
                            .alertName(alert.getAlertName())
                            .id(t++)
                            .build();
                    alertDTOS.add(alertDTO);

                }

            }

            FailureType failureType = failureTypeService.getById(tractsCombination.getFailureId());

            // 构建CombinationDTO对象，包含组合ID和内容，内容为MonitoringTracts列表的字符串表示
            combinationDTOS.add(CombinationDTO.builder()
                    .id(tractsCombination.getId())
                    .tractAlert(alertDTOS)
                    .failureType(failureType)
                    .build());

        }

        // 打印生成的CombinationDTO列表
//        System.out.println(combinationDTOS);

        // 返回CombinationDTO列表
        return combinationDTOS;
    }

    @Override
    public List<CombinationDTO> getCombinationInfoByTract(List<Integer> list) {

        // 获取所有的TractsCombination对象
        List<TractsCombination> tractsCombinationList = this.list()
                .stream()
                .filter(
                      // 查找都包含list的元素
                        tractsCombination -> {
//                            System.out.println(tractsCombination);
                            // 用一个switch语句过滤需要的tract
                            return Objects.equals(tractsCombination.getTractAlertId1(), list.get(0))
                                    && Objects.equals(tractsCombination.getTractAlertId2(), list.get(1))
                                    && Objects.equals(tractsCombination.getTractAlertId3(), list.get(2))
                                    && Objects.equals(tractsCombination.getTractAlertId4(), list.get(3))
                                    && Objects.equals(tractsCombination.getTractAlertId5(), list.get(4));
                        }

                ).toList();



        // 初始化CombinationDTO列表
        List<CombinationDTO> combinationDTOS = new ArrayList<>();

        // 遍历每个TractsCombination对象
        for (TractsCombination tractsCombination : tractsCombinationList) {


            // 获取当前组合中的所有tractId
            List<Integer> tractAlertIds = Arrays.asList(
                    tractsCombination.getTractAlertId1(),
                    tractsCombination.getTractAlertId2(),
                    tractsCombination.getTractAlertId3(),
                    tractsCombination.getTractAlertId4(),
                    tractsCombination.getTractAlertId5()
            );


            // 使用流处理 tractAlertIds 列表，过滤掉空值，根据 ID 获取对应的对象，并再次过滤掉可能的空值，最终收集结果到一个新的列表中
            List<TractsCombination> combinationList = tractAlertIds.stream()
                    .filter(ObjectUtil::isNotEmpty) // 过滤掉空的警报 ID
                    .map(this::getById) // 根据警报 ID 获取对应的 TractsCombination 对象
                    .filter(ObjectUtil::isNotEmpty)
                    .toList();


            List<TractAlertDTO> alertDTOS = new ArrayList<>();
            for (var combination : combinationList) {


                TractAlert alert1 = tractAlertService.getById(combination.getTractAlertId1());
                var alert2 = tractAlertService.getById(combination.getTractAlertId2());
                var alert3 = tractAlertService.getById(combination.getTractAlertId3());
                var alert4 = tractAlertService.getById(combination.getTractAlertId4());
                var alert5 = tractAlertService.getById(combination.getTractAlertId5());

                List<TractAlert> alerts = new ArrayList<>();
                if (alert1 != null) alerts.add(alert1);
                if (alert2 != null) alerts.add(alert2);
                if (alert3 != null) alerts.add(alert3);
                if (alert4 != null) alerts.add(alert4);
                if (alert5 != null) alerts.add(alert5);

                List<MonitoringTracts> tracts = new ArrayList<>();

                int t = 1;
                for (var alert : alerts) {

                    var tractId = alert.getTractId();
                    MonitoringTracts tract = tractsService.getById(tractId);
                    tracts.add(tract);

                    TractAlertDTO alertDTO = TractAlertDTO
                            .builder()
                            .tracts(tract)
                            .alertName(alert.getAlertName())
                            .id(t++)
                            .build();
                    alertDTOS.add(alertDTO);

                }

            }

            FailureType failureType = failureTypeService.getById(tractsCombination.getFailureId());

            // 构建CombinationDTO对象，包含组合ID和内容，内容为MonitoringTracts列表的字符串表示
            combinationDTOS.add(CombinationDTO.builder()
                    .id(tractsCombination.getId())
                    .tractAlert(alertDTOS)
                    .failureType(failureType)
                    .build());

        }

//         打印生成的CombinationDTO列表
        System.out.println(combinationDTOS);

        // 返回CombinationDTO列表
        return combinationDTOS;

    }
}
